package cn.crawler.app.crown.commons.websocket.main.action;

import cn.crawler.framework.util.ClassUtil;
import cn.crawler.framework.util.Result;
import cn.crawler.app.crown.commons.websocket.main.base.NettyRouter;
import cn.crawler.app.crown.commons.websocket.main.base.TextWebSocketFrameHandler;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 22099
 */
public abstract class BaseNettyAction {

    /**
     * 接口-实例
     */
    private static final Map<String, BaseNettyAction> ACTIONS = new HashMap<>();

    static {
        //启动注入 （按理说应该写个IOC容器，不过此处为简易封装就免了，谁闲着没事也可以集成到spring或者nutz
        String thisPackageName = BaseNettyAction.class.getPackage().getName();
        List<Class<?>> classListByAnnotation = ClassUtil.getClassListByAnnotation(thisPackageName.substring(0, thisPackageName.indexOf(".main")), NettyAction.class, true);

        for (Class<?> aClass : classListByAnnotation) {
            try {
                //创建实例
                aClass.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    protected BaseNettyAction() {
        NettyAction nettyAction = this.getClass().getAnnotation(NettyAction.class);
        if (nettyAction == null) {
            Result.breakWith(String.format("Non conforming class:%s\n Cause By Annotation NettyAction not found on the class;", this.getClass()));
        }
//        if (ACTIONS.containsKey(nettyAction.uri())){
        //防止重复注入
//            Result.breakWith(String.format("Already existing uri:", nettyAction.uri()));
//        }
        ACTIONS.put(nettyAction.uri(), this);
    }

    public static BaseNettyAction instance(String uri) {
        BaseNettyAction nettyAction = ACTIONS.get(uri);
        if (nettyAction == null) {
            Result.breakWith(String.format("Uri mapping[%s] not found", uri));
        }
        return nettyAction;
    }

    public static Collection<BaseNettyAction> instances() {
        return ACTIONS.values();
    }


    /**
     * 子类调用此方法获取自己的实例
     * @return
     */
    public static BaseNettyAction instance(Class<? extends BaseNettyAction> clazz) {
        NettyAction nettyAction = null;
        nettyAction = clazz.getAnnotation(NettyAction.class);
        return instance(nettyAction.uri());
    }

    /**
     * 逻辑处理
     *
     * @param params
     * @return
     */
    public abstract Result action(Channel income, JSONObject params);

    /**
     * 开启订阅
     *
     * @return succ为订阅成功将开启订阅推送
     */
    public Result subscribe(NettyRouter router) {
        return Result.error();
    }

    /**
     * 推送数据
     */
    public void push(String key, Object data) {
        String thisUri = this.getClass().getAnnotation(NettyAction.class).uri();
        TextWebSocketFrameHandler.send(thisUri + ":" + key, data);
    }
}
